package com.excel2db.impl;

import com.excel2db.Callback;
import com.excel2db.ExcelReader;
import com.workin.excel.imp.module.ImportExcelData;
import com.workin.excel.imp.module.ImportExcelStruct;
import com.workin.excel.imp.util.ImportDataReader;
import com.workin.excel.imp.util.ParseXMLUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

import java.io.InputStream;
import java.io.PushbackInputStream;
import java.util.List;
import java.util.Map;

/**
 * Created by wxg on 2019/1/3 17:39
 */
public class ExcelReaderImpl implements ExcelReader {
    private InputStream excelFile;
    private InputStream excelXml;
    private SqlSessionFactory sqlSessionFactory;

    /**
     * @param excelFile Target excel file.
     * @param excelXml  Excel xml template.
     */
    public ExcelReaderImpl(InputStream excelFile, InputStream excelXml) {
        this.excelFile = excelFile;
        this.excelXml = excelXml;
    }

    /**
     * @param excelFile      Target excel file.
     * @param excelXml       Excel xml template.
     * @param sessionFactory Mybatis sessionFactory
     */
    public ExcelReaderImpl(InputStream excelFile, InputStream excelXml, SqlSessionFactory sessionFactory) {
        this.excelFile = excelFile;
        this.excelXml = excelXml;
        this.sqlSessionFactory = sessionFactory;
    }

    @Override
    public ImportExcelData read() {
        return read(null);
    }

    @Override
    public ImportExcelData read(Callback callback) {
        try {
            SAXBuilder builder = new SAXBuilder();
            Document document = builder.build(excelXml);
            Element root = document.getRootElement();
            ImportExcelStruct excelStruct = ParseXMLUtil.getInstance().parseImportStruct(root);

            InputStream inp = excelFile;
            int excelType;
            if (!inp.markSupported()) {
                inp = new PushbackInputStream(inp, 8);
            }
            if (POIFSFileSystem.hasPOIFSHeader(inp)) {
                excelType = 1;
            } else if (POIXMLDocument.hasOOXMLHeader(inp)) {
                excelType = 2;
            } else {
                throw new RuntimeException("Unknown file type.");
            }

            ImportExcelData ied = ImportDataReader.readAndValidatorExcel(excelStruct, inp, 0, excelType);
            List<Map<String, Object>> successData = ied.getExcelRightData();
            List<Map<String, Object>> failData = ied.getExcelErrorData();

            if (callback != null) {
                callback.success(successData);
                callback.fail(failData);
            }
            return ied;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public int importToDb(String statement, Object param) {
        SqlSession session = sqlSessionFactory.openSession();
        int count = 0;
        try {
            count = session.insert(statement, param);
            session.commit();
        } catch (Exception e) {
            session.rollback();
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
        return count;
    }

}
